package main

import (
	"flag"
    "bufio"
    "fmt"
    "io"
    "io/ioutil"
    "os"
    "time"
)

func read0(path string) string {
    f, err := ioutil.ReadFile(path)
    if err != nil {
        fmt.Printf("%s\n", err)
        panic(err)
    }
    return string(f)
}

func read1(path string) string {
    fi, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer fi.Close()

    chunks := make([]byte, 1024, 1024)
    buf := make([]byte, 1024)
    for {
        n, err := fi.Read(buf)
        if err != nil && err != io.EOF {
            panic(err)
        }
        if 0 == n {
            break
        }
        chunks = append(chunks, buf[:n]...)
    }
    return string(chunks)
}

func read2(path string) string {
    fi, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer fi.Close()
    r := bufio.NewReader(fi)

    chunks := make([]byte, 1024, 1024)

    buf := make([]byte, 1024)
    for {
        n, err := r.Read(buf)
        if err != nil && err != io.EOF {
            panic(err)
        }
        if 0 == n {
            break
        }
        chunks = append(chunks, buf[:n]...)
    }
    return string(chunks)
}

func read3(path string) string {
    fi, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer fi.Close()
    fd, err := ioutil.ReadAll(fi)
    if err != nil {
        fmt.Println("read to fd fail", err)
        return ""
    }
    return string(fd)
}
/*
经过我的测试，这四种方式读的速度排名是：前者为优
方式四 > 方式一 > 方式三 > 方式二
读文件方式一：利用ioutil.ReadFile直接从文件读取到[]byte中
读文件方式二：读取到file中，再从file读取到buf, buf在追加到最终的[]byte
读文件方式三：读取到file中, 再从file读取到Reader中，从Reader读取到buf, buf最终追加到[]byte
读文件方式四：读取到file中，再利用ioutil将file直接读取到[]byte中
*/

func main() {
/*
	go run xxx.go -file yyyy
*/
	var fileName string
	flag.StringVar(&fileName, "file", "file.mp3", "file name")
	flag.Parse()
	fmt.Println("file name:", fileName)

	file := fileName
	
    start := time.Now()

    read0(file)
    t0 := time.Now()
    fmt.Printf("Cost time %v\n", t0.Sub(start))

    read1(file)
    t1 := time.Now()
    fmt.Printf("Cost time %v\n", t1.Sub(t0))

    read2(file)
    t2 := time.Now()
    fmt.Printf("Cost time %v\n", t2.Sub(t1))

    read3(file)
    t3 := time.Now()
    fmt.Printf("Cost time %v\n", t3.Sub(t2))

}